home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / program / p063b9s.zip / UNIT / OUTMAN2.PAS < prev    next >
Pascal/Delphi Source File  |  1996-04-27  |  23KB  |  807 lines

  1. UNIT OutMan2;
  2. {╔══════════════════════════════════════════════════════════════════════════╗}
  3. {║ Outbound manager v2                           Last changed: 22.04.96  SA ║}
  4. {║                                                                          ║}
  5. {║                         (C) Copyright 1989-96 by                         ║}
  6. {║       Dan Wulff, Jens Sandalgaard, Steen Christensen & S¢ren Ager        ║}
  7. {║                                                                          ║}
  8. {║ This source may not be given to anybody, without the written permission  ║}
  9. {║ from The Portal Team.                                                    ║}
  10. {╚══════════════════════════════════════════════════════════════════════════╝}
  11. {$I POPDEFS.INC}
  12.  
  13. { To-Do-List:
  14.   -----------
  15.     - Config fields/order/size (mellem object PickList->TPickListwFields->TNodePick)
  16.     -
  17.  
  18. }
  19.  
  20. INTERFACE
  21.  
  22. USES Use32, PopTypes;
  23.  
  24. PROCEDURE NewOutboundManager(StartAdr: TFidoAddress);
  25.  
  26. IMPLEMENTATION
  27.  
  28. USES OpCrt, Dos, OpRoot, OpFrame, OpWindow, OpPick, OpString, OpCmd, OpKey,
  29.      OpEntry,
  30.      Globals, Nodelist, Input, FileUtil, OproUtil, MailUtil, StrUtil, Util,
  31.      Display;
  32.  
  33. CONST
  34.   DividerPos = 25;
  35.  
  36. TYPE
  37.   TStatus = (sNotExpandable, sExpandable, sExpanded);
  38.  
  39.   TShowNameAs = (snaName, snaSysName, snaAdr, snaFullAdr);
  40.  
  41.   TMailType = (mtBundle, mtMail, mtAttach, mtPoll,
  42.                mtRequest, mtOldDate, mtUpDate);
  43.  
  44. CONST
  45.   snaFirst = snaName;
  46.   snaLast  = snaFullAdr;
  47.  
  48. TYPE
  49.   PPollNodeES = ^TPollNodeES;
  50.   TPollNodeES = OBJECT(EntryScreen)
  51.     CONSTRUCTOR Init(x, y: Byte);
  52.     PROCEDURE esPostEdit; VIRTUAL;
  53.   END;
  54.  
  55.  
  56.   PMailEntry = ^TMailEntry;
  57.   TMailEntry = OBJECT(SingleListNode)
  58.     FName   : PathStr;
  59.     Stat    : Char;
  60.     Typ     : TMailType;
  61.     Size    : LongInt;
  62.     Time    : LongInt;
  63.     DoAfter : Char;
  64.  
  65.     CONSTRUCTOR Init;
  66.   END;
  67.  
  68.   PNodeInfo = ^TNodeInfo;
  69.   TNodeInfo = OBJECT(SingleListNode)
  70.     Name    : S30;
  71.     SysName : S30;
  72.     Address : TFidoAddress;
  73.     Scanned : Boolean;
  74.     Status  : TStatus;
  75.     MailList: SingleListPtr;
  76.  
  77.     CONSTRUCTOR Init;
  78.     DESTRUCTOR Done; VIRTUAL;
  79.     PROCEDURE FindInNodelist;
  80.     PROCEDURE InsertMail(MailEntry: PMailEntry);
  81.   END;
  82.  
  83.   PNodesList = ^TNodesList;
  84.   TNodesList = OBJECT(SingleList)
  85.  
  86.     PROCEDURE InsertNode(NewNode: PNodeInfo);
  87.     FUNCTION FindNode(Address: TFidoAddress): PNodeInfo;
  88.   END;
  89.  
  90.  
  91.   PNodePick = ^TNodePick;
  92.   TNodePick = OBJECT(PickList)
  93.     ShowNameAs : TShowNameAs;
  94.     NodesList  : PNodesList;
  95.  
  96.     CONSTRUCTOR Init(X1, Y1, X2, Y2 : Byte; ANodes: PnodesList);
  97.     PROCEDURE ItemString(Item: Word; Mode: pkMode; VAR IType: pkItemType; VAR IString: STRING); VIRTUAL;
  98.     PROCEDURE PreMove; VIRTUAL;
  99.     PROCEDURE pkUpdateSearch; VIRTUAL;
  100.     PROCEDURE pkResetSearchStr; VIRTUAL;
  101.   END;
  102.  
  103.   PDetailPick = ^TDetailPick;
  104.   TDetailPick = OBJECT(PickList)
  105.     Node : PNodeInfo;
  106.  
  107.     CONSTRUCTOR Init(X1, Y1, X2, Y2 : Byte);
  108.     PROCEDURE ItemString(Item: Word; Mode: pkMode; VAR IType: pkItemType; VAR IString: STRING); VIRTUAL;
  109.  
  110.     PROCEDURE SetNodePtr(ANode: PNodeInfo);
  111.   END;
  112.  
  113.   POutMan = ^TOutMan;
  114.   TOutMan = OBJECT(StackWindow)
  115.     KeyWin     : WindowPtr;
  116.     NodePick   : PNodePick;
  117.     DetailPick : PDetailPick;
  118.     NodesList  : PNodesList;
  119.     SearchHdr  : Byte;
  120.     Offset     : Word;
  121.  
  122.     CONSTRUCTOR Init;
  123.     DESTRUCTOR Done; VIRTUAL;
  124.     PROCEDURE UpdateContents; VIRTUAL;
  125.     PROCEDURE Process; VIRTUAL;
  126.  
  127.     PROCEDURE UpdateSearch(SearchStr: S20);
  128.  
  129.     PROCEDURE ScanZones;
  130.     PROCEDURE ScanNode(Node: PNodeInfo);
  131.     PROCEDURE ExpandNode(Node: PNodeInfo);
  132.     PROCEDURE CollapseNode(Node: PNodeInfo);
  133.     PROCEDURE ShowNodeInfo(Node: PNodeInfo);
  134.  
  135.     PROCEDURE DeleteMail;
  136.     PROCEDURE MakePoll;
  137.   END;
  138.  
  139.  
  140. {=== TPollNodeES ===}
  141.  
  142.   CONSTRUCTOR TPollNodeES.Init(x, y: Byte);
  143.   BEGIN
  144.   END;
  145.  
  146.   PROCEDURE TPollNodeES.esPostEdit;
  147.   BEGIN
  148. {   IF GetCurrentID=1 THEN GetAdressFromStr(s, Address);}
  149.   END;
  150.  
  151.  
  152. {=== TMailEntry ===}
  153.  
  154.   CONSTRUCTOR TMailEntry.Init;
  155.   BEGIN
  156.     IF NOT INHERITED Init THEN Fail;
  157.     FName:='';
  158.     Stat:=' ';
  159.     Typ:=mtMail;
  160.     Size:=0;
  161.     Time:=0;
  162.     DoAfter:=' ';
  163.   END;
  164.  
  165.  
  166. {=== TNodeInfo ===}
  167.  
  168.   CONSTRUCTOR TNodeInfo.Init;
  169.   BEGIN
  170.     IF NOT INHERITED Init THEN Fail;
  171.     Name:='';
  172.     SysName:='';
  173.     FillChar(Address, SizeOf(Address), 0);
  174.     Scanned:=False;
  175.     Status:=sNotExpandable;
  176.     MailList:=NIL;
  177.   END;
  178.  
  179.   DESTRUCTOR TNodeInfo.Done;
  180.   BEGIN
  181.     IF MailList<>NIL THEN Dispose(MailList, Done);
  182.     INHERITED Done;
  183.   END;
  184.  
  185.   PROCEDURE TNodeInfo.FindInNodelist;
  186.   VAR
  187.     NodeListRec : NodeListRecType;
  188.   BEGIN
  189.     IF FindNode(Address, NodeListRec) THEN
  190.     BEGIN
  191.       IF Address.Net=0 THEN
  192.         Name:=NodeListRec.SystemName
  193.       ELSE
  194.         Name:=NodeListRec.SysopName;
  195.       SysName:=NodeListRec.SystemName;
  196.     END ELSE
  197.     BEGIN
  198.       IF Address.Net=0 THEN
  199.         Name:='Zone '+Long2Str(Address.Zone)
  200.       ELSE
  201.         IF Address.Point=0 THEN
  202.           Name:=Long2Str(Address.Net)+'/'+Long2Str(Address.Node)
  203.         ELSE
  204.           Name:='.'+Long2Str(Address.Point);
  205.       SysName:=Name;
  206.     END;
  207.   END;
  208.  
  209.   PROCEDURE TNodeInfo.InsertMail(MailEntry: PMailEntry);
  210.   BEGIN
  211.     IF MailList=NIL THEN New(MailList, Init);
  212.     MailList^.Append(MailEntry);
  213.   END;
  214.  
  215.  
  216.  
  217. {=== TNodesList ===}
  218.  
  219.   PROCEDURE TNodesList.InsertNode(NewNode: PNodeInfo);
  220.   VAR
  221.     OldAdr, NewAdr : S8;
  222.     Node : PNodeInfo;
  223.   BEGIN
  224.     NewAdr:=Address2Sort(NewNode^.Address);
  225.     Node:=PNodeInfo(Head);
  226.     IF Node<>NIL THEN
  227.     BEGIN
  228.       OldAdr:=Address2Sort(Node^.Address);
  229.       WHILE (Node<>NIL) AND (OldAdr<=NewAdr) DO
  230.       BEGIN
  231.         Node:=PNodeInfo(Next(Node));
  232.         IF Node<>NIL THEN OldAdr:=Address2Sort(Node^.Address);
  233.       END;
  234.     END;
  235.     NewNode^.FindInNodelist;
  236.     IF Node=NIL THEN Append(NewNode) ELSE PlaceBefore(NewNode, Node);
  237.   END;
  238.  
  239.   FUNCTION TNodesList.FindNode(Address: TFidoAddress): PNodeInfo;
  240.   VAR
  241.     Node : PNodeInfo;
  242.   BEGIN
  243.     Node:=PNodeInfo(Head);
  244.     WHILE (Node<>NIL) AND NOT CmpAdr(Address, Node^.Address) DO
  245.     BEGIN
  246.       Node:=PNodeInfo(Next(Node));
  247.     END;
  248.     FindNode:=Node;
  249.   END;
  250.  
  251.  
  252. {=== TNodePick ===}
  253.  
  254.   CONSTRUCTOR TNodePick.Init(X1, Y1, X2, Y2 : Byte; ANodes: PNodesList);
  255.   BEGIN
  256.     IF NOT PickList.InitAbstractDeluxe(X1, Y1, X2, Y2, Cfg.Color[2],
  257.                                        DefWindowOptions, X2-X1+1, 0,                 {Number of picklist items}
  258.                                        PickVertical, SingleChoice,
  259.                                        DefPickOptions and Not pkMinHeight or
  260.                                        pkProcessZero) THEN Fail;
  261.     SetPadSize(1, 1);
  262.     SetSearchMode(PickStringSearch);
  263. {
  264.     wFrame.SetFrameType(NoWindowFrame);
  265.     AddSearchHeader(10, heBL);}
  266. {   SetSelectMarker('>','<'); }
  267.     IF Cfg.Screen.ExplodingWin THEN EnableExplosions(10);
  268.     ShowNameAs:=snaName;
  269.     NodesList:=ANodes;
  270.   END;
  271.  
  272.   PROCEDURE TNodePick.ItemString(Item: Word; Mode: pkMode; var IType: pkItemType; var IString : String);
  273.   VAR
  274.     Node : PNodeInfo;
  275.   BEGIN
  276.     Node:=PNodeInfo(NodesList^.Nth(Item));
  277.     IF Node<>NIL THEN
  278.     BEGIN
  279.       IString:='';
  280.       IF Mode=pkDisplay THEN
  281.       BEGIN
  282.         IF Node^.Address.Net<>0 THEN IString:=' ';
  283.         IF Node^.Address.Point<>0 THEN IString:='  ';
  284.         CASE Node^.Status OF
  285.           sExpandable : IString:=IString+'+';
  286.           sExpanded   : IString:=IString+'-';
  287.           ELSE          IString:=IString+' ';
  288.         END;
  289.       END;
  290.       CASE ShowNameAs OF
  291.         snaName    : IString:=IString+Node^.Name;
  292.         snaAdr     : IF Node^.Address.Net=0 THEN
  293.                        IString:=IString+'Zone '+Long2Str(Node^.Address.Zone)
  294.                      ELSE
  295.                        IF Node^.Address.Point=0 THEN
  296.                          IString:=IString+Long2Str(Node^.Address.Net)+'/'+Long2Str(Node^.Address.Node)
  297.                        ELSE
  298.                          IString:=IString+'.'+Long2Str(Node^.Address.Point);
  299.         snaFullAdr : IString:=IString+Address2Str(Node^.Address);
  300.         snaSysName : IString:=IString+Node^.SysName;
  301.       END;
  302.     END;
  303.   END;
  304.  
  305.   PROCEDURE TNodePick.PreMove;
  306.   BEGIN
  307.     INHERITED PreMove;
  308.     POutMan(wParentPtr)^.DetailPick^.SetNodePtr(PNodeInfo(NodesList^.Nth(pkChoice)));
  309.   END;
  310.  
  311.   PROCEDURE TNodePick.pkUpdateSearch;
  312.   BEGIN
  313.     POutMan(wParentPtr)^.UpdateSearch(pkSearchStr);
  314.   END;
  315.  
  316.   PROCEDURE TNodePick.pkResetSearchStr;
  317.   BEGIN
  318.     INHERITED pkResetSearchStr;
  319.     pkUpdateSearch;
  320.   END;
  321.  
  322.  
  323. {=== TDetailPick ===}
  324.  
  325.   CONSTRUCTOR TDetailPick.Init(X1, Y1, X2, Y2 : Byte);
  326.   BEGIN
  327.     IF NOT PickList.InitAbstractDeluxe(X1, Y1, X2, Y2, Cfg.Color[2],
  328.                                        DefWindowOptions, X2-X1+1, 0,
  329.                                        PickVertical, MultipleChoice,
  330.                                        DefPickOptions and Not pkDrawActive and
  331.                                        Not pkMinHeight or  pkProcessZero) then
  332.       Fail;
  333.     SetPadSize(0, 1);
  334.     SetSelectMarker(#251, '');
  335.     IF Cfg.Screen.ExplodingWin THEN EnableExplosions(10);
  336.     Node:=NIL;
  337.   END;
  338.  
  339.   PROCEDURE TDetailPick.ItemString(Item: Word; Mode: pkMode; var IType: pkItemType; var IString : String);
  340.   VAR
  341.     MailEntry : PMailEntry;
  342.  
  343.     FUNCTION Typ2Str(MailType: TMailType): S10;
  344.     BEGIN
  345.       CASE MailType OF
  346.         mtBundle : Typ2Str:='Bundle  ';
  347.         mtMail   : Typ2Str:='Mail    ';
  348.         mtAttach : Typ2Str:='Attach  ';
  349.         mtPoll   : Typ2Str:='Poll    ';
  350.         mtRequest: Typ2Str:='Req.    ';
  351.         mtOldDate: Typ2Str:='O.Req.  ';
  352.         mtUpDate : Typ2Str:='U.Req.  ';
  353.         ELSE       Typ2Str:='??????  ';
  354.       END;
  355.     END;
  356.  
  357.     FUNCTION Stat2Str(Stat: Char): S10;
  358.     BEGIN
  359.       CASE Stat OF
  360.         'H' : Stat2Str:='Hold  ';
  361.         'D' : Stat2Str:='Dir.  ';
  362.         'F',
  363.         'O' : Stat2Str:='Norm  ';
  364.         'C' : Stat2Str:='Crsh  ';
  365.         'I' : Stat2Str:='Imp.  ';
  366.       END;
  367.     END;
  368.  
  369.   BEGIN
  370.     IF (Node<>Nil) AND (Node^.MailList<>NIL) AND (Node^.MailList^.Size>0) THEN
  371.     BEGIN
  372.       MailEntry:=PMailEntry(Node^.MailList^.Nth(Item));
  373.       WITH MailEntry^ DO
  374.       BEGIN
  375.         IString:=Typ2Str(Typ)+Stat2Str(Stat)+'  '+LongIntForm('########', Size)+'  ';
  376.         IF Typ IN [mtBundle, mtMail] THEN
  377.           IString:=IString+JustFileName(FName)
  378.         ELSE
  379.           IString:=IString+FName;
  380.       END;
  381.     END ELSE
  382.       IString:='* * * * N o t   S c a n n e d   y e t * * * *';
  383.   END;
  384.  
  385.   PROCEDURE TDetailPick.SetNodePtr(ANode: PNodeInfo);
  386.   BEGIN
  387.     Node:=ANode;
  388.     ClearSelected;
  389.     IF NOT Node^.Scanned THEN POutMan(wParentPtr)^.ScanNode(Node);
  390.     IF Node^.MailList<>NIL THEN
  391.       ChangeNumItems(Node^.MailList^.Size)
  392.     ELSE
  393.       IF Node^.Scanned THEN ChangeNumItems(0) ELSE ChangeNumItems(1);
  394.     UpdateContents;
  395.   END;
  396.  
  397.  
  398. {=== TOutMan ===}
  399.  
  400.   CONSTRUCTOR TOutMan.Init;
  401.   BEGIN
  402.     IF NOT INHERITED InitCustom(2, 3, ScreenWidth-1, ScreenHeight-3, Cfg.Color[2],
  403.                                 wClear+wUserContents+wBordered) THEN Fail;
  404.     wFrame.AddSpanHeader('╤', '│', '╧',  DividerPos,  frLL);
  405.     wFrame.AddHeader(' Outbound Manager ',heTC);
  406.     WITH wFrame DO
  407.     BEGIN
  408.       AddHeader('', heBL);
  409. {     IF frRes <> 0 THEN
  410.       BEGIN
  411.         GotError(epFatal+ecOutOfMemory, emInsufficientMemory);
  412.         Exit;
  413.       END; }
  414.       SearchHdr:=GetLastHeaderIndex;
  415.     END;
  416.     IF Cfg.Screen.ExplodingWin THEN EnableExplosions(10);
  417.     Offset:=0;
  418.  
  419.     PickCommands.AddCommand(ccUser0, 1, OpKey.Tab, 0);
  420.     PickCommands.AddCommand(ccUser0, 1, OpKey.ShTab, 0);
  421.     PickCommands.AddCommand(ccUser1, 1, OpKey.Plus, 0);
  422.     PickCommands.AddCommand(ccUser1, 1, OpKey.PadPlus, 0);
  423.     PickCommands.AddCommand(ccUser2, 1, OpKey.Minus, 0);
  424.     PickCommands.AddCommand(ccUser2, 1, OpKey.PadMinus, 0);
  425.  
  426.     PickCommands.AddCommand(ccUser10, 1, OpKey.AltN, 0);
  427.     PickCommands.AddCommand(ccUser11, 1, OpKey.AltI, 0);
  428.  
  429.     PickCommands.AddCommand(ccUser22, 1, OpKey.Del, 0);
  430.     PickCommands.AddCommand(ccUser22, 1, OpKey.F2, 0);
  431.     PickCommands.AddCommand(ccUser28, 1, OpKey.F8, 0);
  432.  
  433.     New(NodesList, Init);
  434.     New(NodePick, Init(2, 3, DividerPos, ScreenHeight-3, NodesList));
  435.     AddChild(NodePick);
  436.     New(DetailPick, Init(DividerPos+2, 4, ScreenWidth-1, ScreenHeight-3));
  437.     AddChild(DetailPick);
  438.     ScanZones;
  439.     MyWin(KeyWin, 1, ScreenHeight-1, ScreenWidth, ScreenHeight, 2, '',False);
  440.     KeyWin^.wFastText('F1=Help          F2=Delete      F3=Request     F4=Send File     F5=ReAddress', 1, 2);
  441.     KeyWin^.wFastText('F6=Change Stat   F7=View File   F8=Poll        F9=Upd. Req.     F0=Global Cmd.', 2, 2);
  442.     Draw;
  443.     SetActiveChild(NodePick);
  444.   END;
  445.  
  446.   DESTRUCTOR TOutMan.Done;
  447.   BEGIN
  448.     KillWindow(KeyWin);
  449.     Dispose(NodesList, Done);
  450.     INHERITED Done;
  451.   END;
  452.  
  453.   PROCEDURE TOutMan.UpdateContents;
  454.   BEGIN
  455.     INHERITED UpdateContents;
  456.     wFastWrite(Pad(' Type    Stat        Size  Filename', ScreenWidth-DividerPos-2),
  457.                1, DividerPos+1, Cfg.Color[2].HighLightColor);
  458.   END;
  459.  
  460.   PROCEDURE TOutMan.Process;
  461.   VAR
  462.     LastCmd : Word;
  463.   BEGIN
  464.     REPEAT
  465.       ActiveChild^.Process;
  466.       LastCmd:=PickListPtr(ActiveChild)^.GetLastCommand;
  467.       CASE LastCmd OF
  468.         ccUser0 : IF TypeOf(wActiveChild^)=TypeOf(TNodePick) THEN
  469.                   BEGIN
  470.                     IF DetailPick^.Node^.Address.Net<>0 THEN
  471.                     BEGIN
  472.                       IF NOT DetailPick^.Node^.Scanned THEN ScanNode(DetailPick^.Node);
  473.                       IF DetailPick^.Node^.MailList<>NIL THEN
  474.                         SetActiveChild(DetailPick);
  475.                      END ELSE
  476.                        IF NOT DetailPick^.Node^.Scanned THEN
  477.                          ExpandNode(DetailPick^.Node);
  478.                    END ELSE
  479.                      SetActiveChild(NodePick);
  480.         ccUser1 : IF TypeOf(wActiveChild^)=TypeOf(TNodePick) THEN
  481.                   BEGIN
  482.                     IF ((NOT DetailPick^.Node^.Scanned) AND (DetailPick^.Node^.Address.Net=0)) OR
  483.                        (DetailPick^.Node^.Status=sExpandable) THEN
  484.                       ExpandNode(DetailPick^.Node);
  485.                   END;
  486.         ccUser2 : IF DetailPick^.Node^.Status=sExpanded THEN CollapseNode(DetailPick^.Node);
  487.  
  488.         ccUser10: BEGIN
  489.                     IF NodePick^.ShowNameAs=snaLast THEN
  490.                       NodePick^.ShowNameAs:=snaFirst
  491.                     ELSE
  492.                       NodePick^.ShowNameAs:=Succ(NodePick^.ShowNameAs);
  493.                     NodePick^.UpdateContents;
  494.                   END;
  495.         ccUser11: IF TypeOf(wActiveChild^)=TypeOf(TNodePick) THEN ShowNodeInfo(DetailPick^.Node);
  496.  
  497.         ccUser22: DeleteMail;
  498.         ccUser28: MakePoll;
  499.       END;
  500.     UNTIL LastCmd=ccQuit;
  501.   END;
  502.  
  503.   PROCEDURE TOutMan.UpdateSearch(SearchStr: S20);
  504.   BEGIN
  505.     ChangeHeader(SearchHdr, Copy(SearchStr, 1, 10));
  506.   END;
  507.  
  508.   PROCEDURE TOutMan.ScanZones;
  509.   VAR
  510.     Node: PNodeInfo;
  511.     p,
  512.     OutName : S12;
  513.     Test,
  514.     GlobZone: Integer;
  515.     SRec    : SearchRec;
  516.   BEGIN
  517.     FindFirst(Cfg.Outbound+'.*', Directory, SRec);
  518.     OutName:=JustFileName(Cfg.Outbound);
  519.     GlobZone:=0;
  520.     WHILE DOSError=0 DO
  521.     BEGIN
  522.       Test:=0;
  523.       IF SRec.Name=OutName THEN
  524.         GlobZone:=Cfg.Addresses[Cfg.MainAdrNum].Zone
  525.       ELSE
  526.       BEGIN
  527.         p:=Copy(Srec.Name, pos('.', Srec.Name)+1, Length(Srec.Name) - pos('.', Srec.Name)+1);
  528.         Val('$'+p, GlobZone, Test);
  529.         IF GlobZone=Cfg.Addresses[Cfg.MainAdrNum].Zone THEN
  530.         BEGIN
  531.           FindNext(SRec);
  532.           Continue;
  533.         END;
  534.       END;
  535.       IF (Test=0) AND (GlobZone<>0) THEN
  536.       BEGIN
  537.         New(Node, Init);
  538.         Node^.Address.Zone:=GlobZone;
  539.         Node^.Status:=sExpandable;
  540.         NodesList^.InsertNode(Node);
  541.       END;
  542.       FindNext(Srec);
  543.     END;
  544.     FindClose(Srec);
  545.     NodePick^.ChangeNumItems(NodesList^.Size);
  546.   END;
  547.  
  548.   PROCEDURE TOutMan.ScanNode(Node: PNodeInfo);
  549.   CONST
  550.     Attach         : String[6] = 'HDFCI ';
  551.     Mail           : String[6] = 'HDOCI ';
  552.   VAR
  553.     SRec, SRec1 : SearchRec;
  554.     ZoneOut,
  555.     FileOut     : PathStr;
  556.     a, Try      : Byte;
  557.     MailEntry   : PMailEntry;
  558.     f           : TBufTextFile;
  559.     InStr       : String;
  560.     GotOne      : Boolean;
  561.     Count       : Word;
  562.   BEGIN
  563.     FileOut:=HoldFileName(Node^.Address, False);
  564.     ZoneOut:=HoldAreaPath(Node^.Address, False);
  565.  
  566. {    FindFirst(FileOut+'*.PKT',Archive,SRec) ;
  567.     IF (DosError=0) And (Confirm('Orphan packets found, rename','Y',13)) THEN
  568.     BEGIN
  569.       REPEAT
  570.         RenamePkt(ZoneOut,SRec.FName);
  571.         FindNext(SRec);
  572.         Wait^.Animate;
  573.       UNTIL DosError<>0;
  574.     END;}
  575.  
  576.     FOR a:=1 TO 5 DO
  577.     BEGIN
  578.       FindFirst(FileOut+Mail[a]+'UT', Archive, SRec);
  579.       WHILE DOSError = 0 DO
  580.       BEGIN
  581. {        IF SRec.Size<>0 THEN}
  582.         BEGIN
  583.           New(MailEntry, Init);
  584.           WITH MailEntry^ DO
  585.           BEGIN
  586.             FName:=SRec.Name;
  587.             Stat:=Mail[a];
  588.             Typ:=mtBundle;
  589.             Size:=SRec.Size;
  590.             Time:=SRec.Time;
  591.           END;
  592.           Node^.InsertMail(MailEntry);
  593.         END;
  594. {       Wait^.Animate;}
  595.         FindNext(SRec);
  596.       END;
  597.       FindClose(SRec);
  598.     END;
  599.     FindFirst(FileOut+'REQ', Archive, SRec);
  600.     WHILE DOSError = 0 DO
  601.     BEGIN
  602.       IF (SRec.size>0) AND (f.Init(ZoneOut+SRec.Name, SOpenread+ShareDenyNone, 10240)) THEN
  603.       BEGIN
  604.         GotOne:=False;
  605.         WHILE NOT f.EoF DO
  606.         BEGIN
  607.           f.ReadLn(InStr);
  608.           InStr:=StUpCase(InStr);
  609.           IF (InStr[1] <> ';') AND (Length(InStr) > 0) THEN
  610.           BEGIN
  611.             GotOne:=True;
  612.             New(MailEntry, Init);
  613.             MailEntry^.Typ:=mtRequest;
  614.             Try:=Pos(' ',InStr);
  615.             IF (Try>0) And (pos('-', InStr)>Try) THEN MailEntry^.Typ:=mtOldDate;
  616.             IF (Try>0) And (pos('+', InStr)>Try) THEN MailEntry^.Typ:=mtUpDate;
  617.             IF Try >0  THEN InStr:=Copy(InStr, 1, Try-1);
  618.             MailEntry^.FName:=InStr;
  619.             Node^.InsertMail(MailEntry);
  620.           END;
  621. {         Wait^.Animate;}
  622.         END;
  623.         f.Done;
  624.         IF NOT GotOne THEN DeleteFile(FileOut+SRec.Name);
  625.       END;
  626.       FindNext(SRec);
  627.     END;
  628.     FindClose(SRec);
  629.  
  630.     FOR a:=1 TO 5 DO
  631.     BEGIN
  632.       FindFirst(FileOut+Attach[a]+'LO', Archive, SRec);
  633.       WHILE DOSERROR = 0 DO
  634.       BEGIN
  635.         Count:=0;
  636.         IF (SRec.size>0) AND (f.Init(ZoneOut+SRec.Name, SOpenread+ShareDenyNone, 10240)) THEN
  637.         BEGIN
  638.           WHILE NOT F.EoF DO
  639.           BEGIN
  640.             f.ReadLn(InStr);
  641.             InStr:=StUpCase(InStr);
  642.             IF (Length(InStr)>0) AND (InStr[1]<>';') AND (InStr[1]<>'~') THEN
  643.             BEGIN
  644.               New(MailEntry, Init);
  645.               IF (InStr[1] = '#') OR (InStr[1] = '^') THEN
  646.               BEGIN
  647.                 MailEntry^.DoAfter:=InStr[1];
  648.                 InStr:=Copy(InStr, 2, Length(InStr) - 1);
  649.               END;
  650.               WITH MailEntry^ DO
  651.               BEGIN
  652.                 FName:=InStr;
  653.                 Stat:=Attach[a];
  654.                 FindFirst(FName, AnyFile, SRec1);
  655.                 IF DOSError=0 THEN
  656.                 BEGIN
  657.                   Size:=SRec1.Size;
  658.                   Time:=SRec1.Time;
  659.                 END;
  660.                 IF Copy(FName, 1, Length(ZoneOut))=ZoneOut THEN
  661.                   Typ:=mtMail
  662.                 ELSE
  663.                   Typ:=mtAttach;
  664.               END;
  665.               Inc(Count);
  666.               Node^.InsertMail(MailEntry);
  667.             END;
  668. {           Wait^.Animate;}
  669.           END;
  670.           f.Done;
  671.         END;
  672.         IF Count=0 THEN
  673.         BEGIN
  674.           New(MailEntry, Init);
  675.           WITH MailEntry^ DO
  676.           BEGIN
  677.             Stat:=Attach[a];
  678.             Typ:=mtPoll;
  679.           END;
  680.           Node^.InsertMail(MailEntry);
  681.         END;
  682.         FindNext(SRec);
  683.       END;
  684.       FindClose(SRec);
  685.     END;
  686.  
  687.     Node^.Scanned:=True;
  688.   END;
  689.  
  690.   PROCEDURE TOutMan.ExpandNode(Node: PNodeInfo);
  691.   VAR
  692.     NewNode : PNodeInfo;
  693.     SRec : SearchRec;
  694.     Path : PathStr;
  695.     Err  : Integer;
  696.     FoundSome : Boolean;
  697.     Adr       : TFidoAddress;
  698.     WaitWin : PWait;
  699.   BEGIN
  700.     New(WaitWin, Init(ScreenHeight DIV 2, 3, 'Scannning: '+Node^.Name));
  701.     IF Node^.Address.Net<>0 THEN
  702.     BEGIN
  703.       Adr:=Node^.Address;
  704.       Adr.Point:=1;
  705.       Path:=HoldAreaPath(Adr, False)+'*.*';
  706.     END ELSE
  707.       Path:=HoldAreaPath(Node^.Address, False)+'*.*';
  708.     FoundSome:=False;
  709.     FindFirst(Path, AnyFile, SRec);
  710.     WHILE DOSError=0 DO
  711.     BEGIN
  712.       IF (Length(SRec.Name)>=8) AND
  713.       ((Copy(SRec.Name, 11, 2)='LO') OR (Copy(SRec.Name, 11, 2)='UT') OR
  714.        (Copy(SRec.Name, 10, 3)='REQ') OR (Copy(SRec.Name, 10, 3)='PNT')) THEN
  715.       BEGIN
  716.         Adr.Zone:=Node^.Address.Zone;
  717.         Val('$'+Copy(SRec.Name, 1, 4), Adr.Net, Err);
  718.         Val('$'+Copy(SRec.Name, 5, 4), Adr.Node, Err);
  719.         Adr.Point:=0;
  720.         IF (Adr.Net=0) THEN
  721.         BEGIN
  722.           Adr.Point:=Adr.Node;
  723.           Adr.Net:=Node^.Address.Net;
  724.           Adr.Node:=Node^.Address.Node;
  725.         END;
  726.         NewNode:=NodesList^.FindNode(Adr);
  727.         IF NewNode=NIL THEN
  728.         BEGIN
  729.           New(NewNode, Init);
  730.           NewNode^.Address:=Adr;
  731.           NodesList^.InsertNode(NewNode);
  732.         END;
  733.         IF (Copy(SRec.Name, 10, 3)='PNT') AND (Adr.Point=0) THEN NewNode^.Status:=sExpandable;
  734.         FoundSome:=True;
  735.       END;
  736.       FindNext(SRec);
  737.       WaitWin^.Animate;
  738.     END;
  739.     FindClose(SRec);
  740.     NodePick^.ChangeNumItems(NodesList^.Size);
  741.     IF FoundSome THEN
  742.       Node^.Status:=sExpanded
  743.     ELSE
  744.       Node^.Status:=sNotExpandable;
  745.     Node^.Scanned:=True;
  746.     Dispose(WaitWin, Done);
  747.   END;
  748.  
  749.   PROCEDURE TOutMan.CollapseNode(Node: PNodeInfo);
  750.   VAR
  751.     AdrStr : S6;
  752.     NewNode : PNodeInfo;
  753.     Len : Byte;
  754.   BEGIN
  755.     IF Node^.Address.Net=0 THEN Len:=2 ELSE Len:=6;
  756.     AdrStr:=Copy(Address2Sort(Node^.Address), 1, Len);
  757.     NewNode:=PNodeInfo(NodesList^.Next(Node));
  758.     WHILE (NewNode<>NIL) AND (AdrStr=Copy(Address2Sort(NewNode^.Address), 1, Len)) DO
  759.     BEGIN
  760.       NodesList^.Delete(NewNode);
  761.       NewNode:=PNodeInfo(NodesList^.Next(Node));
  762.     END;
  763.     Node^.Status:=sExpandable;
  764.     NodePick^.ChangeNumItems(NodesList^.Size);
  765.   END;
  766.  
  767.   PROCEDURE TOutMan.ShowNodeInfo(Node: PNodeInfo);
  768.   VAR
  769.     NodeInfoWin : WindowPtr;
  770.   BEGIN
  771.     MyWin(NodeInfoWin, 20, 8, 60, 19, 2, 'Node information',False);
  772. { Fill in code!!!! }
  773.     ReadKeyWord;
  774.     KillWindow(NodeInfoWin);
  775.   END;
  776.  
  777.  
  778.   PROCEDURE TOutMan.DeleteMail;
  779.   BEGIN
  780.     IF DetailPick^.Node^.Address.Net=0 THEN
  781.     BEGIN
  782.       IF Confirm('Delete ALL mail in: ','N',13) THEN ;
  783.  
  784.     END ELSE
  785.       IF Confirm('Delete mail for: ','N',13) THEN ;
  786.  
  787.   END;
  788.  
  789.   PROCEDURE TOutMan.MakePoll;
  790.   BEGIN
  791.  
  792.   END;
  793.  
  794.  
  795. {=== ===}
  796.  
  797.   PROCEDURE NewOutboundManager(StartAdr: TFidoAddress);
  798.   VAR
  799.     OutMan: TOutMan;
  800.   BEGIN
  801.     OutMan.Init;
  802.     OutMan.Process;
  803.     OutMan.Done;
  804.   END;
  805.  
  806. END.
  807.